package util;

import net.sf.json.JSONObject;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Created by yanglq on 2018/4/9.
 */
public class HttpUtil {

    private final static Logger logger = LoggerFactory.getLogger(HttpUtil.class);
    private final static String UTF_8 = "utf-8";

    private HttpUtil() {
        throw new AssertionError();
    }

    public static String generateURL(Map<String, String> params, String Url) {
        List<String> allEncodeParams = getAllParams(params);
        String cqsString = getCQS(allEncodeParams);
        return Url + "?" + cqsString;
    }

    private static List<String> getAllParams(Map<String, String> params) {
        List<String> encodeParams = new ArrayList<String>();
        if (params != null) {
            for (String key : params.keySet()) {
                String encodeVal = null;
                String value = params.get(key);
                // 将参数和值都urlEncode一下。
                String encodeKey = percentEncode(key);
                if (value != null) {
                    encodeVal = percentEncode(value);
                }
                encodeParams.add(encodeKey + "=" + encodeVal);
            }
        }
        return encodeParams;
    }

    /**
     * 获取CQS 的字符串
     *
     * @param allParams
     * @return
     */
    private static String getCQS(List<String> allParams) {
        String cqString = "";
        for (int i = 0; i < allParams.size(); i++) {
            cqString += allParams.get(i);
            if (i != allParams.size() - 1) {
                cqString += "&";
            }
        }
        return cqString;
    }


    /**
     * 参数urlEncode
     *
     * @param value
     * @return
     */
    private static String percentEncode(String value) {
        try {
            String urlEncodeOrignStr = URLEncoder.encode(value, UTF_8);
            String plusReplaced = urlEncodeOrignStr.replace("+", "%20");
            String starReplaced = plusReplaced.replace("*", "%2A");
            return starReplaced.replace("%7E", "~");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return value;
    }

    public static JSONObject httpGet(String url, String token) throws IOException {
        CloseableHttpClient httpclient = HttpClients.createDefault();
        HttpGet httpGet = new HttpGet(url);
        //所有请求需在请求头设置accessToken
        if (token != null)
            httpGet.setHeader("accessToken", token);
        JSONObject json = null;
        try (CloseableHttpResponse response2 = httpclient.execute(httpGet)) {
            HttpEntity entity2 = response2.getEntity();
            String respContent = EntityUtils.toString(entity2, UTF_8);
//            logger.info(response2.getStatusLine().toString());
//            logger.info(respContent);
            if (response2.getStatusLine().getStatusCode() == 200) {
                json = JSONObject.fromObject(respContent);
            }
            EntityUtils.consume(entity2);
        }
        return json;
    }

    public static boolean httpPost(String url, List<NameValuePair> info) throws IOException {
        CloseableHttpClient httpclient = HttpClients.createDefault();
        HttpPost httpPost = new HttpPost(url);
        httpPost.setHeader("Content-type", "text/json");

        //设置参数到请求对象中
        httpPost.setEntity(new UrlEncodedFormEntity(info, UTF_8));
        boolean flag;
        try (CloseableHttpResponse response2 = httpclient.execute(httpPost)) {
            HttpEntity entity2 = response2.getEntity();
            String respContent = EntityUtils.toString(entity2, UTF_8);
            logger.info(response2.getStatusLine().toString());
            logger.info(respContent);
            flag = response2.getStatusLine().getStatusCode() == 200;
            EntityUtils.consume(entity2);
        }
        return flag;
    }
}
